(function () {
  'use strict';

  angular
    .module('client')
    .factory('controlService', controlService);

  controlService.$inject = ['$http', '$log', '$websocket', '$cookies', '$resource', '$q', '$document',
    'WS_API', 'PLAYER_STREAM_TYPE', 'CONTROL_API', 'KEYBOARD_CONTROL_TABLE', 'indexService', 'utilService'];
  function controlService($http, $log, $websocket, $cookies, $resource, $q, $document,
                          WS_API, PLAYER_STREAM_TYPE, CONTROL_API, KEYBOARD_CONTROL_TABLE, indexService, utilService) {
    var services = {
      getPhoneScreenSize: getPhoneScreenSize,
      initPlayerStream: initPlayerStream,
      getToolbar: getToolbar,
      convertKey: convertKey,
      keycode: keycode,
      releaseDevice: releaseDevice,
      closeWebSockets: closeWebSockets,
      restTime: restTime,
      getDeviceModel: getDeviceModel,
    };

    return services;

    var ws;
    var size = {
      screenWidth: undefined,
      screenHeight: undefined,
    };

    function getPhoneScreenSize() {
      size = indexService.getDeviceSize();
      if (!size.screenWidth || !size.screenHeight) {
        return false;
      }
      return true;
    }


    function initPlayerStream(options /*opts: ctrl: controller, ele: canvas's parent element, id: devedce id*/) {
      //show users have been use h264 or not
      var self = options.ctrl;
      var playerElement = options.ele;
      var deviceID = options.id;

      controlShowH264({ctrl: self, ele: playerElement, id: deviceID});
    }

    function getToolbar(name) {
      var toolbar = !!name ? name : $cookies.get('control_toolbar');
      if (!toolbar) {
        toolbar = 'control.logs';
      }
      $cookies.put('control_toolbar', toolbar);
      return toolbar;
    }

    function convertKey(event) {
      var keyCode = event.keyCode;
      //var alt = undefined;
      if(event.ctrlKey) {
        if(65 <= keyCode && keyCode <= 90) {
          keyCode += 179;
        }
      }
      if(event.shiftKey) {
        if(48 <= keyCode && keyCode <= 57) {
          keyCode += 174;
        }
        else if(186 <= keyCode && keyCode <= 192) {
          keyCode += 47;
        }
        else if(219 <= keyCode && keyCode <= 222) {
          keyCode += 21;
        }
      }
      keycode(KEYBOARD_CONTROL_TABLE.keys[keyCode]);
    }

    function keycode(code) {
      if (ws) {
        ws.send({type: "opt", data: 'k ' + code});
      }
    }

    function controlShowH264(options) {
      var self = options.ctrl;
      var playerElement = options.ele;
      var deviceID = options.id;

      var deviceVideo;
      var render = new RawRenderer(true);
      var canvas = render.getCanvas();
      var playerStream = $websocket(WS_API.video);
      var time;

      $(playerElement).append(canvas);
      deviceVideo = $(canvas);

      playerStream.onOpen(function () {
        playerStream.send(JSON.stringify({type: PLAYER_STREAM_TYPE.video, uuid: deviceID}));
        $log.debug('open stream');
        ws = playerStream;
      });

      playerStream.onClose(function (event) {
        //  TODO: give some tips when server close the connect
        $log.debug('player websocket was closed');
        $log.debug(event.code);
        console.log(event.reason);
        ws = undefined;
      });

      playerStream.onMessage(function (msg) {
        render.onDecodeMessage(msg.data);
        screenResize(self, $(playerElement).attr('rotate'), {width: deviceVideo.width(), height: deviceVideo.height()});
        //resize()
      });

      bindTouchesEvent(deviceVideo, playerStream);
    }

    function bindTouchesEvent(ele, socket) {
      var mousedown = false;

      ele.on('dragstart', function () {
        return false;
      });

      ele.on('mousedown', function (event) {
        event.preventDefault();
        mousedown = true;
        var pos = getMousePos(ele, event);
        socket.send({type: "opt", data: "d 0 " + pos.x + " " + pos.y + " 50\nc"});
        //$log.debug("d 0 " + pos.x + " " + pos.y + " 50\nc");
      });

      ele.on('mouseup', function (event) {
        if (mousedown) {
          mousedown = false;
          socket.send({type: "opt", data: "u 0\nc"});
          //$log.debug("u 0\nc");
        }
      });

      ele.on('mouseout', function (event) {
        if (mousedown) {
          mousedown = false;
          socket.send({type: "opt", data: "u 0\nc"});
          //$log.debug("u 0\nc");
        }
      });

      ele.on('mousemove', function (event) {
        if (mousedown) {
          var pos = getMousePos(ele, event);
          socket.send({type: "opt", data: "m 0 " + pos.x + " " + pos.y + " 50\nc"});
          //$log.debug("m 0 " + pos.x + " " + pos.y + " 50\nc");
        }
      });
    }

    function getMousePos(canvas, event) {
      var rect = $(canvas).offset();
      var res = {
        x: Math.ceil((event.clientX - rect.left + $document.scrollLeft()) * size.screenWidth / $(canvas).width()),
        y: Math.ceil((event.clientY - rect.top + $document.scrollTop()) * size.screenHeight / $(canvas).height())
      }
      return res;
    }

    function screenResize(self, dir, options) {
      //$log.debug(options);
      var width = parseInt(options.width);
      var height = parseInt(options.height);

      if (width > height && 'horizontal' !== dir) {
        swapSize('horizontal');
        self.rotate = 'horizontal';
      }
      else if (height > width && 'vertical' !== dir) {
        // $(ele).attr('rotate' ,'vertical');
        swapSize('vertical');
        self.rotate = 'vertical';
      }
    }

    function releaseDevice(deviceID) {
      var q = $q.defer();
      $resource(CONTROL_API.releaseDevice, {deviceID: deviceID})
        .delete(
          {},
          function (resp) {
            q.resolve(resp);
          },
          function (resp) {
            q.reject(resp)
          });
      return q.promise;
    }

    function closeWebSockets() {
      if (ws) {
        ws.close();
      }
    }

    function restTime() {
      var time = indexService.getLocalTime();
      var localTime = time.localTime;
      var duration = time.duration * 60;
      var flag = false;
      var rest;
      var t;

      if(!time) {
        flag = false;
      }

      t = (Date.parse(new Date()) - localTime) / 1000;
      rest = duration - t;

      if (rest < 0) {
        flag = true;
        rest = 0;
      }
      else {
        flag = false;
      }

      return {
        over: flag,
        minute: utilService.formatNumber(Math.floor(rest / 60), 2),
        second: utilService.formatNumber(Math.floor(rest % 60), 2),
      };
    }

    function getDeviceModel() {
      return indexService.getDeviceModel();
    }

    function swapSize(dirt) {
      var w = size.screenWidth;
      var h = size.screenHeight;
      var temp;
      if (!w || !h) {
        return false;
      }
      if (dirt === 'horizontal' && (w > h)) {
        return true;
      }
      if (dirt === 'vertical' && (w < h)) {
        return true;
      }
      temp = size.screenHeight;
      size.screenHeight = size.screenWidth;
      size.screenWidth = temp;
      return true;
    }

  }
})();
